package club.emergency.wechat.common.excel;

import club.emergency.wechat.exeception.common.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;

/**
 * Create with IntelliJ IDEA
 * Project Name: wechat
 * Package Name: club.emergency.wechat.common.excel
 * Date: 2018/12/3
 *
 * @author: 快乐的小菌菌
 * Description: Excel处理类
 */
@Slf4j
public class XlsExcelProcess {
    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";

    /**
     * 分析Excel,只能存在单一sheet。
     *
     * @param suffix 文件后缀名
     * @param bytes  以byte数组方式传入，dubbo不支持大数据流方式传参
     * @param isFillNull 空行是否填充null。根据需要设置。
     * @return map
     */
    public static Map<Integer, List<String>> process(String suffix, byte[] bytes, Boolean isFillNull) {
        Map<Integer, List<String>> map = new HashMap<>();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        try {
            Workbook workbook = null;
            try {
                if (XLS.equals(suffix)) {
                    workbook = new HSSFWorkbook(byteArrayInputStream);
                } else if (XLSX.equals(suffix)) {
                    workbook = new XSSFWorkbook(byteArrayInputStream);
                } else {
                    throw new CommonException("传入的Excel文件格式错误！");
                }
            } catch (NotOfficeXmlFileException exception) {
                throw new CommonException("传入的Excel文件格式错误，请检查是否真的为Excel文档！");
            } finally {
                byteArrayInputStream.close();
            }
            for (Sheet sheet : workbook) {
                int lastRowNum = sheet.getLastRowNum() + 1;
                for (int i = 0; i < lastRowNum; i++) {
                    List<String> list = new ArrayList<>();
                    Row row = sheet.getRow(i);
                    if (Objects.isNull(row)) {
                        break;
                    }
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        Cell cell = row.getCell(j);
                        if (Objects.nonNull(cell)) {
                            switch (cell.getCellType()) {
                                case STRING:
                                    String stringCellValue = cell.getStringCellValue();
                                    list.add(stringCellValue);
                                    break;
                                case NUMERIC:
                                    String numericCellValue = cell.getNumericCellValue() + "";
                                    list.add(numericCellValue);
                                    break;
                                case BLANK:
                                    if (isFillNull) {
                                        list.add(null);
                                    }
                                    break;
                                case _NONE:
                                    break;
                                default:
                                    if (isFillNull) {
                                        list.add(null);
                                    }
                                    break;
                            }
                        }
                    }
                    map.put(i, list);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                byteArrayInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
}
